package cn.wawi.controller;

import java.beans.PropertyEditorSupport;
import java.lang.reflect.ParameterizedType;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.wawi.common.R;
import cn.wawi.common.StringEscapeEditor;
import cn.wawi.common.annotation.MapperName;
import cn.wawi.common.base.SqlBuilder;
import cn.wawi.common.filter.DbcontextHolder;
import cn.wawi.dao.DaoSupport;
import cn.wawi.entity.sys.User;
import cn.wawi.utils.DateUtil;
import cn.wawi.utils.QueryUtil;
import cn.wawi.utils.StrKit;
import cn.wawi.utils.StringUtil;
import jodd.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
/**
 * <--------------基础控制器-------------->
 * @author 龚亮
 * @date 2015-05-25 14:49:35
 */
@SuppressWarnings("all")
public abstract class BaseController<T> {
	
	@Resource
	private DaoSupport dao;
	private String mapperName;
	private String mainName;
	
	@InitBinder
	public void init(WebDataBinder binder) {
		// String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击、sql注入
		binder.registerCustomEditor(String.class, new StringEscapeEditor(true,false,true));
		
		// Date 类型转换
		binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(DateUtil.parseDate(text));
			}
		});
		
		// Timestamp 类型转换
		binder.registerCustomEditor(Timestamp.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				Date date = DateUtil.parseDate(text);
				setValue(date==null?null:new Timestamp(date.getTime()));
			}
		});
	}

	public BaseController(){
		try {
			ParameterizedType pt=(ParameterizedType) this.getClass().getGenericSuperclass();
			Class<T> clazz=(Class<T>) pt.getActualTypeArguments()[0];
			mainName=clazz.getPackage().getName().substring(clazz.getPackage().getName().lastIndexOf(".")+1)+"/"+clazz.getSimpleName()+"/main";
			mapperName=clazz.getName().replaceAll("entity", "dao")+"Dao";
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	/**
	 * 查询所有(不分页)
	 * @return DataGrid
	 */
	@ResponseBody
	@RequestMapping(value="/findAll",method={RequestMethod.GET,RequestMethod.POST})
	public R findAll(HttpServletRequest request){
		List<T> list=dao.findAll(mapperName, QueryUtil.setNoPage(request));
		return success("请求成功!").put(list, list.size());
	}
	@ResponseBody
	@RequestMapping(value="/findOne",method={RequestMethod.GET,RequestMethod.POST})
	public R findOne(T t){
		t=dao.findOne(mapperName,t);
		return success("请求成功!").put(t);
	}
	/**
	 * 分页查询
	 * @return DataGrid
	 */
	@ResponseBody
	@RequestMapping(value="/findAllByPage",method={RequestMethod.GET,RequestMethod.POST})
	public R findAllByPage(HttpServletRequest request){
		List<T> list=dao.findAll(mapperName, QueryUtil.setPage(request));
		PageInfo<T> pages = new PageInfo<T>(list);
		return success("请求成功!").put(pages.getList(),pages.getTotal());
	}

	/**
	 *根据一组id删除
	 */
	@ResponseBody
	@RequestMapping(value="/deleteBatch",method=RequestMethod.POST)
	public R deleteBatch(T t,@RequestParam(value="ids[]",required=true)String[] ids){
		if(ids==null||ids.length==0){
			return error("ids不能为空!");
		}
		if(t instanceof User){
			if(ArrayUtils.contains(ids,getUser().getId().toString())){
				return error("当前用户不能删除!");
			}
			if(ArrayUtils.contains(ids,"1")){
				return error("管理员不能删除!");
			}
		}
		return dao.deleteBatch(mapperName,ids)>0?success("删除成功!"):success("删除失败!");
	}
	/**
	 *根据一组id批量逻辑删除
	 */
	@ResponseBody
	@RequestMapping(value="/updateBatch",method=RequestMethod.POST)
	public R updateBatch(@RequestParam(value="ids[]",required=true)String[] ids){
		if(ids==null||ids.length==0){
			return error("ids不能为空!");
		}
		return dao.updateBatch(mapperName,ids)>0?success("删除成功!"):success("删除失败!");
	}
	
	@ResponseBody
	@RequestMapping(value="/deleteOne",method={RequestMethod.POST})
	public R deleteOne(T t,String id){
		if(StringUtils.isBlank(id)){
			return error("id不能为空!");
		}
		if(t instanceof User){
			if(id.equals(getUser().getId().toString())){
				return error("当前用户不能删除!");
			}
			if("1".equals(id)){
				return error("管理员不能删除!");
			}
		}
		return dao.deleteOne(mapperName,id)==1?success("删除成功!"):success("删除失败!");
	}

	/**
	 *添加或者修改
	 *主键id不为空时更新,否则保存
	 */
	@ResponseBody
	@RequestMapping(value="/saveORupdate",method=RequestMethod.POST)
	public R<T> saveORupdate(T t){
		if(t==null){
			return error("请求参数不能为空!");
		}
		if(t instanceof User){
			String password=BeanUtil.declared.getProperty(t, "password");
			if(StrKit.isBlank(password))
				password="123456";
			BeanUtil.declared.setProperty(t, "password",new Md5Hash(password,BeanUtil.declared.getProperty(t,"password"),2).toString());
		}
		if(StrKit.notNull(BeanUtil.declared.getProperty(t, SqlBuilder.getPrimaryKey(t)))){
			dao.updateOne(mapperName, t);
		}else{
			dao.saveOne(mapperName, t);
		}
		return success("保存或更新成功!").put(t);
	}
	

	
	public R<T> success(String resMsg){
		return new R<T>(resMsg);
	}
	public R<T> error(String resMsg){
		return new R<T>(0,resMsg);
	}
	
	public User getUser(){
		return (User) SecurityUtils.getSubject().getPrincipal();
	}
	@RequestMapping(value="/main",method={RequestMethod.GET})
	public String mainView(){
		return mainName;
	}
}